﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SGS.Standard.Actor;
using SGS.Standard.Delegate;
using SGS.Standard.EventArgs;
using SGS.Cards;
using SGS.Characters;

namespace SGS.Standard
{
    public class GameContext
    {
        #region Construct
        public GameContext()
        {
            PlayersCircle = new PlayerCollection();
        }

        public static GameContext Current
        {
            get
            {
                return GamePool.Current;
            }
        }
        #endregion

        #region Internal Config Member
        public bool EnableSkipActor
        {
            get
            {
                return true;
            }
        }
        #endregion

        #region Internal Member
        protected Thread _gameThread;
        #endregion

        #region Game Running Member
        public PlayerCollection PlayersCircle
        {
            get;
            set;
        }

        private Player _CurrentPlayer;
        public Player CurrentPlayer
        {
            get
            {
                return _CurrentPlayer;
            }
            protected set
            {
                _CurrentPlayer = value;
            }
        }

        /*public PlayerDistanceCollection CalcPlayerDistance( Player from )
        {

        }*/

        public SystemCardHeap CardHeap
        {
            get;
            protected set;
        }
        #endregion

        #region Notice Message Event
        public event NoticeMessageEventHandler OnNoticeMessage;

        public void RaiseNoticeMessageEvent(string msg, params object[] args)
        {
            RaiseNoticeMessageEvent(this, msg, args);
        }

        public void RaiseNoticeMessageEvent(object sender, string msg, params object[] args)
        {
            if (OnNoticeMessage != null)
            {
                OnNoticeMessage(sender, string.Format(msg, args));
            }
        }
        #endregion

        #region Human Actor Event
        public event HumanActorEventHandler OnHunanActor;

        internal void RaiseHumanActorEvent(object sender, HumanActorEventArgs eq, HumanAnswerActorEventArgs ea)
        {
            if (!eq.AnswerPlayer.GameInfo.Live)
            {
                RaiseNoticeMessageEvent(GamePool.Current, "{0} 已经死亡，无法应答, 系统自动应答Skip", eq.AnswerPlayer.PlayerName);
                ea.AnswerActor = new SkipActor();
                return;
            }

            if (OnHunanActor != null)
            {
                while (ea.AnswerActor == null)
                {
                    OnHunanActor(sender, eq, ea);

                    if (!this.EnableSkipActor)
                    {
                        if (ea.AnswerActor is Actor.SkipActor)
                        {
                            ea.AnswerActor = null;
                        }
                    }

                    if (ea.AnswerActor != null)
                    {
                        break;
                    }
                }
            }
            else
            {
                return;
            }
        }
        #endregion

        #region Game Context Controller
        public virtual void Start()
        {
            if (_gameThread == null || _gameThread.ThreadState == ThreadState.Stopped)
            {
                _gameThread = new Thread(new ThreadStart(GameLogicMain));
                _gameThread.Start();
            }
        }

        public bool IsRunning()
        {
            return _gameThread != null && _gameThread.ThreadState != ThreadState.Stopped;
        }

        public virtual void Stop()
        {
            _gameThread.Abort();
            _gameThread = null;
        }

        protected virtual void GameInit()
        {
            if (OnHunanActor == null)
            {
                throw new Exception("Game error, no OnHunanActor event listener");
            }

            int dummy = 0;
            foreach( var p in PlayersCircle )
            {
                p.GameInfo = new PlayerGameInfo(p, dummy, new Characters.Woodman() );
                dummy++;
            }
            
            var gameCards = DataConstructor.CreateDefaultCardsForTest();
            gameCards.Shuffle();

            CardHeap = new SystemCardHeap(gameCards);
        } 
        #endregion

        #region Game Main Logic
        protected void GameLogicMain()
        {
            GamePool.Instance.Set( this );

            GameInit();
            GL_GameStart();

            SGS.Standard.GameLogic.QueryController.NMQC_ShowPlayerState();

            RaiseNoticeMessageEvent("Game Start");
            
            this.CurrentPlayer = PlayersCircle.First.Value;
            
            while (CurrentPlayer != null && CurrentPlayer.GameInfo.Live )
            {
                if (CurrentPlayer.GameInfo.Live)
                {
                    SGS.Standard.GameLogic.PlayerTurn.GL_PlayerTurn( this.CurrentPlayer );

                    if (GL_CheckGameEnd())
                    {
                        break;
                    }
                }
                    
                this.CurrentPlayer = PlayersCircle.GetCircleNode( this.CurrentPlayer ).Next.Value;

                Thread.Sleep(200);
            }
            
            RaiseNoticeMessageEvent(this, "Game Over");
        }

        protected bool GL_CheckGameEnd()
        {
            if (PlayersCircle.Count() <= 1)
            {
                RaiseNoticeMessageEvent(this, "Players count <= 1");
                return true;
            }

            return false;
        }

        protected virtual void GL_GameStart()
        {
            foreach (var p in PlayersCircle)
            {
                p.GameInfo.OwnCards.PushToStart( CardHeap.GetCards(4) );
            }
        }
        #endregion
    }
}
